home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Extensions / img / imgtiffmodule.c < prev   
Text File  |  1995-12-21  |  20KB  |  766 lines

  1. /***********************************************************
  2. Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
  3. Amsterdam, The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI not be used in advertising or publicity pertaining to
  13. distribution of the software without specific, written prior permission.
  14.  
  15. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  18. FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /*
  26. ** Partially derived from tifftopnm.c and pnmtotiff.c, which were written
  27. ** by Jeff Poskanzer, who in turn derived them from ras2tif.c and tis2ras.c,
  28. ** which are:
  29. **
  30. ** Copyright (c) 1990 by Sun Microsystems, Inc.
  31. **
  32. ** Author: Patrick J. Naughton
  33. ** naughton@wind.sun.com
  34. **
  35. ** Permission to use, copy, modify, and distribute this software and its
  36. ** documentation for any purpose and without fee is hereby granted,
  37. ** provided that the above copyright notice appear in all copies and that
  38. ** both that copyright notice and this permission notice appear in
  39. ** supporting documentation.
  40. **
  41. ** This file is provided AS IS with no warranties of any kind.  The author
  42. ** shall have no liability with respect to the infringement of copyrights,
  43. ** trade secrets or any patents by this file or any part thereof.  In no
  44. ** event will the author be liable for any lost revenue or profits or
  45. ** other special, indirect and consequential damages.
  46. */
  47.  
  48. /*
  49. ** Note: the code could do with some optimalization. The inner loop
  50. ** in tiff_read() is rather big and contains multiple special cases,
  51. ** which could be separated out or something. Oh well, It'll be faster
  52. ** than decoding tiff files in python:-)
  53. */
  54.  
  55. #include "allobjects.h"
  56. #include "modsupport.h"        /* For getargs() etc. */
  57. #include "import.h"
  58.  
  59. #include "tiffio.h"
  60.  
  61. /* The image formats we support */
  62. static PyObject *format_rgb, *format_rgb_b2t, *format_grey,
  63.           *format_grey_b2t, *format_choices;
  64. extern PyObject *getimgformat();    /* Get format by name */
  65.  
  66. /* TIFF error handling */
  67.  
  68. char tifferrstr[1000];
  69. static TIFFErrorHandler prevErr;
  70. static TIFFErrorHandler prevWarn;
  71. #define TIFF_END TIFFSetErrorHandler(prevErr); TIFFSetWarningHandler(prevWarn);
  72. #define TIFF_START prevErr = TIFFSetErrorHandler(my_tifferror); \
  73.                   prevWarn = TIFFSetWarningHandler(my_tiffwarning);
  74.  
  75. static void
  76. my_tiffwarning(const char *module, const char *fmt, va_list ap)
  77. {
  78.     /* Ignore warnings */
  79. }
  80.  
  81. static void
  82. my_tifferror(const char *module, const char *fmt, va_list ap)
  83. {
  84.     char *ptr = tifferrstr;
  85.  
  86.     if ( module ) {
  87.     sprintf(ptr, "%s: ", module);
  88.     ptr += strlen(ptr);
  89.     }
  90.     vsprintf(ptr, fmt, ap);
  91. }
  92.  
  93. /* Tiff objects */
  94. typedef int tifpix;        /* I assume this is correct? Always? */
  95.  
  96. typedef struct {
  97.     PyObject_HEAD
  98.     PyObject    *dict;        /* Attributes dictionary */
  99.     int    is_reader;    /* TRUE if this is a reader */
  100.     char    *filename;    /* filename of the image file */
  101.     TIFF    *filep;
  102.     tifpix    maxval;        /* Max pixel value in tiff file */
  103.     float     factor;        /* Convert maxval to 0xff */
  104.     unsigned short photomet;/* TIFF "filetype" */
  105.     unsigned short bps;    /* bits per sample */
  106.     unsigned short spp;    /* samples per pixel */
  107. } tiffobject;
  108.  
  109. static PyObject *errobject;
  110.  
  111. staticforward PyTypeObject Tifftype;
  112.  
  113. #define is_tiffobject(v)        ((v)->ob_type == &Tifftype)
  114.  
  115. static char doc_tiff[] = "This object reads/writes TIFF files.\n"
  116.     "The 'width', 'height' and 'format' attributes give info about the\n"
  117.     "image data read (or to be written)";
  118.  
  119. /* Routine to easily obtain C data from the dict python data */
  120. int
  121. tiffselfattr(self, name, fmt, ptr, wanterr)
  122.     tiffobject *self;
  123.     char *name;
  124.     char *fmt;
  125.     void *ptr;
  126.     int wanterr;
  127. {
  128.     PyObject *obj;
  129.     char errbuf[100];
  130.  
  131.     obj = PyDict_GetItemString(self->dict, name);
  132.     if ( obj == NULL ) {
  133.     if ( wanterr ) {
  134.         sprintf(errbuf, "Required attribute '%s' not set", name);
  135.         PyErr_SetString(errobject, errbuf);
  136.         return 0;
  137.     } else {
  138.         PyErr_Clear();
  139.         return 0;
  140.     }
  141.     }
  142.     if ( !PyArg_Parse(obj, fmt, ptr) ) {
  143.     if ( !wanterr )
  144.         PyErr_Clear();
  145.     return 0;
  146.     }
  147.     return 1;
  148. }
  149.  
  150. /* Routine to easily insert integer into dictionary */
  151. tiffsetintattr(self, name, value)
  152.     tiffobject *self;
  153.     char *name;
  154.     int value;
  155. {
  156.     PyObject *obj;
  157.     int rv;
  158.  
  159.     obj = PyInt_FromLong(value);
  160.     rv = PyDict_SetItemString(self->dict, name, obj);
  161.     Py_DECREF(obj);
  162.     return rv;
  163. }
  164.  
  165. static tiffobject *
  166. newtiffobject()
  167. {
  168.     tiffobject *xp;
  169.     xp = PyObject_NEW(tiffobject, &Tifftype);
  170.     if (xp == NULL)
  171.         return NULL;
  172.     xp->dict = PyDict_New();
  173.     xp->filename = NULL;
  174.     xp->filep = NULL;
  175.     return xp;
  176. }
  177.  
  178. static int
  179. inittiffreader(self, name)
  180.     tiffobject *self;
  181.     char *name;
  182. {
  183.     char *name_copy;
  184.     int cols, rows;
  185.     unsigned short bps, spp, photomet;
  186.     tifpix maxval;
  187.     PyObject *ourformat;
  188.  
  189.     if( (name_copy=malloc(strlen(name)+1)) == NULL ) {
  190.     PyErr_NoMemory();
  191.     return 0;
  192.     }
  193.     strcpy(name_copy, name);
  194.     self->filename = name_copy;
  195.     self->is_reader = 1;
  196.  
  197.     TIFF_START
  198.     if ((self->filep = TIFFOpen(self->filename, "r")) == NULL ) {
  199.     PyErr_SetString(errobject, tifferrstr);
  200.     TIFF_END
  201.     return 0;
  202.     }
  203.     
  204.     if ( ! TIFFGetField( self->filep, TIFFTAG_BITSPERSAMPLE, &bps ) )
  205.     bps = 1;
  206.     if ( ! TIFFGetField( self->filep, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
  207.     spp = 1;
  208.     if ( ! TIFFGetField( self->filep, TIFFTAG_PHOTOMETRIC, &photomet ) ) {
  209.     PyErr_SetString(errobject, "No photometric tag");
  210.     TIFF_END
  211.     return 0;
  212.     }
  213.  
  214.     switch ( spp ) {
  215.     case 1:
  216.     case 3:
  217.     case 4:
  218.     break;
  219.  
  220.     default:
  221.     PyErr_SetString(errobject,
  222.         "can only handle 1-channel gray scale or 1- or 3-channel color" );
  223.     TIFF_END
  224.     return 0;
  225.     }
  226.  
  227.     (void) TIFFGetField( self->filep, TIFFTAG_IMAGEWIDTH, &cols );
  228.     (void) TIFFGetField( self->filep, TIFFTAG_IMAGELENGTH, &rows );
  229.     TIFF_END
  230.     
  231.     maxval = ( 1 << bps ) - 1;
  232.     self->maxval = maxval;
  233.     if ( maxval != 255 ) {
  234.     self->factor = 255.0/(float)maxval;
  235.     /*DBG  printf("TIFF factor: %e (%d)\n", self->factor, maxval); */
  236.     }
  237.     self->bps = bps;
  238.     self->spp = spp;
  239.     self->photomet = photomet;
  240.     if ( maxval == 1 && spp == 1 ) {
  241.     ourformat = format_grey;
  242.     } else {
  243.     switch ( photomet ) {
  244.     case PHOTOMETRIC_MINISBLACK:
  245.         ourformat = format_grey;
  246.         break;
  247.  
  248.     case PHOTOMETRIC_MINISWHITE:
  249.         ourformat = format_grey;
  250.         break;
  251.  
  252.     case PHOTOMETRIC_PALETTE:
  253.         PyErr_SetString(errobject, "Cannot handle PALETTE format yet");
  254.         return 0;
  255.  
  256.     case PHOTOMETRIC_RGB:
  257.         ourformat = format_rgb;
  258.         break;
  259.  
  260.     case PHOTOMETRIC_MASK:
  261.         PyErr_SetString(errobject, "Cannot handle PHOTOMETRIC_MASK" );
  262.         return 0;
  263.  
  264.     default:
  265.         PyErr_SetString(errobject, "Unknown photometric type");
  266.         return 0;
  267.     }
  268.     }
  269.  
  270.     TIFF_END
  271.  
  272.     tiffsetintattr(self, "width", cols);
  273.     tiffsetintattr(self, "height", rows);
  274. #if 0
  275.     tiffsetintattr(self, "bps", (int)bps);
  276.     tiffsetintattr(self, "spp", (int)spp);
  277. #endif
  278.     PyDict_SetItemString(self->dict, "format", ourformat);
  279.     PyDict_SetItemString(self->dict, "format_choices", format_choices);
  280.     if ( PyErr_Occurred() )
  281.     return 0;
  282.     return 1;
  283. }
  284.  
  285. static int
  286. inittiffwriter(self, name)
  287.     tiffobject *self;
  288.     char *name;
  289. {
  290.     char *name_copy;
  291.  
  292.     if( (name_copy=malloc(strlen(name)+1)) == NULL ) {
  293.     PyErr_NoMemory();
  294.     return 0;
  295.     }
  296.     strcpy(name_copy, name);
  297.     self->filename = name_copy;
  298.  
  299.     self->is_reader = 0;
  300.     PyDict_SetItemString(self->dict, "format", format_rgb);
  301.     PyDict_SetItemString(self->dict, "format_choices", format_choices);
  302.     if( PyErr_Occurred())
  303.     return 0;
  304.     return 1;
  305. }
  306.  
  307. /* Tiff methods */
  308.  
  309. static void
  310. tiff_dealloc(xp)
  311.     tiffobject *xp;
  312. {
  313.     Py_XDECREF(xp->dict);
  314.     if( xp->filename )
  315.         free(xp->filename);
  316.     if( xp->filep )
  317.         TIFFClose(xp->filep);
  318.     PyMem_DEL(xp);
  319. }
  320.  
  321. static char doc_read[] = "Read the actual data, returns a string";
  322.  
  323. static PyObject *
  324. tiff_read(self, args)
  325.     tiffobject *self;
  326.     PyObject *args;
  327. {
  328.         int w, h, toptobottom, havegrey, wantgrey, rowlen;
  329.     int row, col, bitsleft;
  330.     PyObject *rv;
  331.     long *rgbdatap=0;
  332.     char *greydatap=0;
  333.     tifpix greysample, redsample, greensample, bluesample, maxval;
  334.     PyObject *fmt;
  335.     unsigned char *buf, *inP;
  336.     unsigned short bps, spp, photomet;
  337.     
  338.     if (!PyArg_ParseTuple(args,""))
  339.         return NULL;
  340.     if (!self->is_reader) {
  341.         PyErr_SetString(errobject, "Cannot read() from writer object");
  342.         return NULL;
  343.     }
  344.     /* XXXX Read data and return it */
  345.     /* XXXX Get args from self->dict and write the data */
  346.     if ( !tiffselfattr(self, "width", "i", &w, 1) ||
  347.          !tiffselfattr(self, "height", "i", &h, 1) ||
  348.          !tiffselfattr(self, "format", "O", &fmt, 1) )
  349.         return NULL;
  350.     if ( fmt == format_rgb || fmt == format_grey )
  351.         toptobottom = 1;
  352.     else if ( fmt == format_rgb_b2t || fmt == format_grey_b2t )
  353.         toptobottom = 0;
  354.     else {
  355.         PyErr_SetString(errobject, "Unsupported image format");
  356.         return NULL;
  357.     }
  358.     if ( fmt == format_rgb || fmt == format_rgb_b2t )
  359.         wantgrey = 0;
  360.     else
  361.         wantgrey = 1;
  362.     
  363.     rv = 0;
  364.  
  365.     rowlen = w;
  366.     
  367.     if ( wantgrey ) {
  368.         rowlen = (rowlen+3) & ~3; /* pad to 32-bit boundary */
  369.         if ( (rv=PyString_FromStringAndSize(0, rowlen*h)) == NULL )
  370.         return NULL;
  371.         greydatap = PyString_AsString(rv);
  372.         rgbdatap = 0;
  373.     } else {
  374.         if ( (rv=PyString_FromStringAndSize(0, rowlen*h*4)) == NULL )
  375.         return NULL;
  376.         rgbdatap = (long *)PyString_AsString(rv);
  377.         greydatap = 0;
  378.     }
  379.     
  380.     if ( !toptobottom ) {
  381.         greydatap = greydatap + rowlen*(h-1);
  382.         rgbdatap = rgbdatap + rowlen*(h-1);
  383.         rowlen = -rowlen;
  384.     }
  385.  
  386.     havegrey = (self->photomet != PHOTOMETRIC_RGB);
  387.     bps = self->bps;
  388.     maxval = self->maxval;
  389.     spp = self->spp;
  390.     photomet = self->photomet;
  391.     
  392.     buf = (unsigned char *)malloc(TIFFScanlineSize(self->filep));
  393.     if ( buf == NULL ) {
  394.         Py_DECREF(rv);
  395.         PyErr_NoMemory();
  396.         return NULL;
  397.     }
  398.  
  399.     TIFF_START
  400.  
  401. #define NEXTSAMPLE(which) \
  402.     { \
  403.     if ( bitsleft == 0 ) \
  404.     { \
  405.     ++inP; \
  406.     bitsleft = 8; \
  407.     } \
  408.     bitsleft -= bps; \
  409.     which = ( *inP >> bitsleft ) & maxval; \
  410.     }
  411.  
  412.         row = 0;
  413.     while( row < h ) {
  414.         if ( TIFFReadScanline( self->filep, buf, row, 0) < 0) {
  415.         PyErr_SetString(errobject, tifferrstr);
  416.         free(buf);
  417.         TIFF_END
  418.         return NULL;
  419.         }
  420.         inP = buf;
  421.         bitsleft = 8;
  422.         
  423.         for( col=0; col<w; col++ ) {
  424.         switch(photomet) {
  425.         case PHOTOMETRIC_MINISBLACK:
  426.             NEXTSAMPLE(greysample);
  427.             break;
  428.         case PHOTOMETRIC_MINISWHITE:
  429.             NEXTSAMPLE(greysample);
  430.             greysample = maxval - greysample;
  431.             break;
  432.         case PHOTOMETRIC_RGB:
  433.             NEXTSAMPLE(redsample);
  434.             NEXTSAMPLE(greensample);
  435.             NEXTSAMPLE(bluesample);
  436.             if ( spp == 4 )
  437.             NEXTSAMPLE(greysample); /* Ignored alpha */
  438.             break;
  439.         default:
  440.             PyErr_SetString(errobject, "Unknown photometric (cannot happen)");
  441.             free(buf);
  442.             TIFF_END
  443.             return NULL;
  444.         }
  445.         if ( !havegrey && wantgrey ) {
  446.             greysample = (int)(0.299*redsample+0.587*greensample+
  447.                        0.114*bluesample);
  448.             if ( greysample > 255 ) greysample = 255;
  449.         } else if ( havegrey && !wantgrey ) {
  450.             redsample = greensample = bluesample = greysample;
  451.         }
  452.         if ( wantgrey ) {
  453.             if ( maxval != 255 ) {
  454.             greysample = (int)((float)greysample*self->factor);
  455.             if ( greysample > 255 )
  456.                 greysample = 255;
  457.             }
  458.             greydatap[col] = greysample;
  459.         } else {
  460.             if ( maxval != 255 ) {
  461.             redsample = (int)((float)redsample*self->factor);
  462.             if ( redsample > 255 )
  463.                 redsample = 255;
  464.             greensample = (int)((float)greensample*self->factor);
  465.             if ( greensample > 255 )
  466.                 greensample = 255;
  467.             bluesample = (int)((float)bluesample*self->factor);
  468.             if ( bluesample > 255 )
  469.                 bluesample = 255;
  470.             }
  471.             rgbdatap[col] = redsample | (greensample<<8) |
  472.             (bluesample<<16);
  473.         }
  474.         }
  475.         /* Zero-out remaining bytes */
  476.         if ( wantgrey )
  477.         while( col < rowlen )
  478.             greydatap[col++] = 0;
  479.         rgbdatap += rowlen;
  480.         greydatap += rowlen;
  481.         row++;
  482.     }
  483.         TIFF_END
  484.     free(buf);
  485.     return rv;
  486. }
  487.  
  488. static char doc_write[] = "Write (string) data to the TIFF file.";
  489.  
  490. static PyObject *
  491. tiff_write(self, args)
  492.     tiffobject *self;
  493.     PyObject *args;
  494. {
  495.         long *rgbdata;
  496.     char *greydata;
  497.     int datalen, lenwanted;
  498.     unsigned char *buf, *tP;
  499.     int i, w, h, rowlen, row;
  500.     PyObject *fmt;
  501.     long rgbpixel;
  502.     unsigned short photomet, spp;
  503.     int bytesperrow;
  504.     long rowsperstrip;
  505.     TIFF *filep;
  506.     
  507.     if (!PyArg_ParseTuple(args, "s#", &greydata, &datalen))
  508.         return NULL;
  509.     if (self->is_reader) {
  510.         PyErr_SetString(errobject, "Cannot write() to reader object");
  511.         return NULL;
  512.     }
  513.     /* XXXX Get args from self->dict and write the data */
  514.     if ( !tiffselfattr(self, "width", "i", &w, 1) ||
  515.          !tiffselfattr(self, "height", "i", &h, 1) ||
  516.          !tiffselfattr(self, "format", "O", &fmt, 1) )
  517.         return NULL;
  518.  
  519.     rowlen = w;
  520.     if ( fmt == format_rgb || fmt == format_rgb_b2t ) {
  521.         spp = 3;
  522.         photomet = PHOTOMETRIC_RGB;
  523.         lenwanted = w*h*4;
  524.         rgbdata = (long *)greydata;
  525.         greydata = 0;
  526.     } else if ( fmt == format_grey || fmt == format_grey_b2t ) {
  527.         spp = 1;
  528.         photomet = PHOTOMETRIC_MINISBLACK;
  529.         rowlen = (w+3) &~3;
  530.         lenwanted = rowlen*h;
  531.         rgbdata = 0;
  532.     } else {
  533.         PyErr_SetString(errobject, "Unsupported image format");
  534.         return NULL;
  535.     }
  536.     
  537.     if( datalen != lenwanted ) {
  538.         PyErr_SetString(errobject, "Incorrect datasize");
  539.         return NULL;
  540.     }
  541.     
  542.     if ( fmt == format_rgb_b2t || fmt == format_grey_b2t ) {
  543.         rgbdata = rgbdata + rowlen*(h-1);
  544.         greydata = greydata + rowlen*(h-1);
  545.         rowlen = -rowlen;
  546.     }
  547.  
  548.     bytesperrow = spp*w;
  549.     rowsperstrip = 8192 / bytesperrow; /* ??? from pnmtotiff */
  550.     
  551.     if( (buf = malloc(bytesperrow)) == NULL ) {
  552.         PyErr_NoMemory();
  553.         return NULL;
  554.     }
  555.     
  556.     TIFF_START
  557.     if ((filep = TIFFOpen(self->filename, "w")) == NULL) {
  558.         PyErr_SetString(errobject, tifferrstr);
  559.         TIFF_END
  560.         return 0;
  561.     }
  562.  
  563.     TIFFSetField(filep, TIFFTAG_IMAGEWIDTH, w);
  564.     TIFFSetField(filep, TIFFTAG_IMAGELENGTH, h);
  565.     TIFFSetField(filep, TIFFTAG_BITSPERSAMPLE, 8);
  566.     TIFFSetField(filep, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); /*XXX*/
  567.     TIFFSetField(filep, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
  568.     TIFFSetField(filep, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
  569.     TIFFSetField(filep, TIFFTAG_PHOTOMETRIC, photomet);
  570.     TIFFSetField(filep, TIFFTAG_SAMPLESPERPIXEL, spp);
  571.     TIFFSetField(filep, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
  572.     TIFFSetField(filep, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  573.     TIFFSetField(filep, TIFFTAG_SOFTWARE, "Python TIFF module");
  574.  
  575.  
  576.     row = 0;
  577.     while( row < h ) {
  578.         tP = buf;
  579.         for(i=0; i<w; i++) {
  580.         if ( photomet == PHOTOMETRIC_RGB ) {
  581.             rgbpixel = rgbdata[i];
  582.             *tP++ = rgbpixel & 0xff;
  583.             *tP++ = (rgbpixel>>8) & 0xff;
  584.             *tP++ = (rgbpixel>>16) & 0xff;
  585.         } else {
  586.             *tP++ = greydata[i];
  587.         }
  588.         }
  589.         if ( TIFFWriteScanline(filep, buf, row, 0) < 0 ) {
  590.         free(buf);
  591.         PyErr_SetString(errobject, tifferrstr);
  592.         return 0;
  593.         }
  594.         rgbdata += rowlen;
  595.         greydata += rowlen;
  596.         row = row+1;
  597.     }
  598.     TIFFFlushData(filep);
  599.     TIFFClose(filep);
  600.     free(buf);
  601.     Py_INCREF(Py_None);
  602.     return Py_None;
  603. }
  604.         
  605. static struct PyMethodDef tiff_methods[] = {
  606.     {"read",    (PyCFunction)tiff_read,        1,    doc_read},
  607.     {"write",    (PyCFunction)tiff_write,    1,    doc_write},
  608.     {NULL,        NULL}        /* sentinel */
  609. };
  610.  
  611. static PyObject *
  612. tiff_getattr(xp, name)
  613.     tiffobject *xp;
  614.     char *name;
  615. {
  616.         PyObject *v;
  617.     
  618.     if (xp->dict != NULL) {
  619.             if ( strcmp(name, "__dict__") == 0 ) {
  620.                 Py_INCREF(xp->dict);
  621.             return xp->dict;
  622.         }
  623.                if ( strcmp(name, "__doc__") == 0 ) {
  624.                 return PyString_FromString(doc_tiff);
  625.         }
  626.     v = PyDict_GetItemString(xp->dict, name);
  627.         if (v != NULL) {
  628.             Py_INCREF(v);
  629.             return v;
  630.         }
  631.     }
  632.     return Py_FindMethod(tiff_methods, (PyObject *)xp, name);
  633. }
  634.  
  635. static int
  636. tiff_setattr(xp, name, v)
  637.     tiffobject *xp;
  638.     char *name;
  639.     PyObject *v;
  640. {
  641.     if (xp->dict == NULL) {
  642.         xp->dict = PyDict_New();
  643.         if (xp->dict == NULL)
  644.             return -1;
  645.     }
  646.     if (v == NULL) {
  647.         int rv = PyDict_DelItemString(xp->dict, name);
  648.         if (rv < 0)
  649.             PyErr_SetString(PyExc_AttributeError,
  650.                     "delete non-existing imgtiff attribute");
  651.         return rv;
  652.     }
  653.     else
  654.         return PyDict_SetItemString(xp->dict, name, v);
  655. }
  656.  
  657. static PyTypeObject Tifftype = {
  658.     PyObject_HEAD_INIT(&PyType_Type)
  659.     0,            /*ob_size*/
  660.     "imgtiff",        /*tp_name*/
  661.     sizeof(tiffobject),    /*tp_basicsize*/
  662.     0,            /*tp_itemsize*/
  663.     /* methods */
  664.     (destructor)tiff_dealloc, /*tp_dealloc*/
  665.     0,            /*tp_print*/
  666.     (getattrfunc)tiff_getattr, /*tp_getattr*/
  667.     (setattrfunc)tiff_setattr, /*tp_setattr*/
  668.     0,            /*tp_compare*/
  669.     0,            /*tp_repr*/
  670.     0,            /*tp_as_number*/
  671.     0,            /*tp_as_sequence*/
  672.     0,            /*tp_as_mapping*/
  673.     0,            /*tp_hash*/
  674. };
  675.  
  676. static char doc_newreader[] =
  677.     "Return an object that reads the TIFF file passed as argument";
  678.  
  679. static PyObject *
  680. tiff_newreader(self, args)
  681.     PyObject *self;
  682.     PyObject *args;
  683. {
  684.         char *filename;
  685.     tiffobject *obj;
  686.     
  687.     if (!PyArg_ParseTuple(args, "s", &filename))
  688.         return NULL;
  689.     if ((obj = newtiffobject()) == NULL)
  690.         return NULL;
  691.     if ( !inittiffreader(obj, filename) ) {
  692.         tiff_dealloc(obj);
  693.         return NULL;
  694.     }
  695.     return (PyObject *)obj;
  696. }
  697.  
  698. static char doc_newwriter[] =
  699.     "Return an object that writes the TIFF file passed as argument";
  700.  
  701. static PyObject *
  702. tiff_newwriter(self, args)
  703.     PyObject *self;
  704.     PyObject *args;
  705. {
  706.         char *filename;
  707.     tiffobject *obj;
  708.     
  709.     if (!PyArg_ParseTuple(args, "s", &filename))
  710.         return NULL;
  711.     if ((obj = newtiffobject()) == NULL)
  712.         return NULL;
  713.     if ( !inittiffwriter(obj, filename) ) {
  714.         tiff_dealloc(obj);
  715.         return NULL;
  716.     }
  717.     return (PyObject *)obj;
  718. }
  719.  
  720.  
  721. /* List of functions defined in the module */
  722.  
  723. static struct PyMethodDef tiff_module_methods[] = {
  724.     {"reader",    tiff_newreader,    1,    doc_newreader},
  725.     {"writer",    tiff_newwriter,    1,    doc_newwriter},
  726.     {NULL,        NULL}        /* sentinel */
  727. };
  728.  
  729.  
  730. /* Initialization function for the module (*must* be called initimgtiff) */
  731. static char doc_imgtiff[] = "Module to read and write TIFF image files";
  732.  
  733. void
  734. initimgtiff()
  735. {
  736.     PyObject *m, *d, *x, *formatmodule, *formatdict;
  737.  
  738.     /* Create the module and add the functions */
  739.     m = Py_InitModule("imgtiff", tiff_module_methods);
  740.  
  741.     /* Add some symbolic constants to the module */
  742.     d = PyModule_GetDict(m);
  743.     errobject = PyString_FromString("imgtiff.error");
  744.     PyDict_SetItemString(d, "error", errobject);
  745.     x = PyString_FromString(doc_imgtiff);
  746.     PyDict_SetItemString(d, "__doc__", x);
  747.  
  748.     /* Get supported formats */
  749.     if ((formatmodule = PyImport_ImportModule("imgformat")) == NULL)
  750.         Py_FatalError("imgtiff depends on imgformat");
  751.     if ((formatdict = PyModule_GetDict(formatmodule)) == NULL)
  752.         Py_FatalError("imgformat has no dict");
  753.     
  754.  
  755.     format_rgb = PyDict_GetItemString(formatdict,"rgb");
  756.     format_rgb_b2t = PyDict_GetItemString(formatdict,"rgb_b2t");
  757.     format_grey = PyDict_GetItemString(formatdict,"grey");
  758.     format_grey_b2t = PyDict_GetItemString(formatdict,"grey_b2t");
  759.     format_choices = Py_BuildValue("(OOOO)", format_rgb, format_rgb_b2t,
  760.                  format_grey, format_grey_b2t);
  761.  
  762.     /* Check for errors */
  763.     if (PyErr_Occurred())
  764.         Py_FatalError("can't initialize module imgtiff");
  765. }
  766.